package object_inspector;

import java.lang.annotation.Annotation;
import java.lang.reflect.*;

public class Viewer1 {

	private static String TAB = "    ";
	
	private ParentA obj0;
	
	
	public void test(){
		obj0 = new ChildA();
		
		// List hierarchy
		System.out.println("Inheritance Hieracrhy");
		Class c0 = obj0.getClass();
		while(c0 != null && c0.getSuperclass() != null){
			displayClass(c0, "");
			c0 = c0.getSuperclass();
		}
	}
	
	private void displayClass(Class c, String indent){
		System.out.println(indent + "----------------------------------------");
		String modifiers =  Modifier.toString(c.getModifiers());
		System.out.println(indent + modifiers + " " + c.getSimpleName());
		Class[] ics = c.getInterfaces();
		if(ics != null && ics.length > 0)
			System.out.println(indent + TAB + "Interfaces");
			for(Class ic : ics)
				displayClass(ic, indent + TAB);
		displayFields(c, indent + TAB);
		displayMethods(c, indent + TAB);
		Class[] dc = c.getDeclaredClasses();
		if(dc != null)
			for(Class mc : dc)
				displayClass(mc, indent + TAB);
		System.out.println(indent + "----------------------------------------");
	}
	
	private void displayFields(Class c, String indent){
		Field[] fields = c.getDeclaredFields();
		if(fields.length > 0){
			System.out.println(indent + "Fields");
			for(Field field : fields){
				String modifiers =  Modifier.toString(field.getModifiers());
				String type = field.getType().getName();
				String name = field.getName();
				System.out.println(indent + modifiers + " " + type + " " + name);
			}
		}
	}
	
	private void displayMethods(Class c, String indent){
		Method[] method = c.getDeclaredMethods();
		if(method.length > 0){
			System.out.println(indent + "Methods");
			for(Method m : method){
				String modifiers =  Modifier.toString(m.getModifiers());
				String name = m.getName();
				String retType = m.getReturnType().getSimpleName();
				Annotation[] ans = m.getDeclaredAnnotations();
				if(ans != null && ans.length > 0) {
					System.out.println(indent + "Annotations");
					for(Annotation a : ans)
						System.out.println(indent + a.toString());
				}
				System.out.println(indent + modifiers + " " + retType  + " " + name);
				displayParameters(m, indent + "    > ");
			}
		}
	}
	
	private void displayParameters(Method method, String indent){
		Class[] types = method.getParameterTypes();
		for(int i = 0; i < types.length; i++){
			System.out.println(indent +  types[i].getName());
		}
	}
	
	public static void main(String[] args) {
		Viewer1 that = new Viewer1();
		
		that.test();
	}

}
